package com.walker.component.page.resolve;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.util.Map;

import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import bsh.EvalError;
import bsh.Interpreter;

import com.walker.component.page.resolve.exception.JsonException;
import com.walker.component.page.resolve.exception.PageResolveException;
import com.walker.component.page.resolve.factory.JsonQueryerFactory;
import com.walker.component.page.resolve.query.Queryer;

/**
 * 页面解析
 * 
 * @author 三丰
 * 
 */
public class PageResolve {
	private String templatePath;
	private static PageResolve pageResolve;

	/**
	 * 定义json模板的位置
	 * 
	 * @param templatePath
	 */
	public void setTemplatePath(String templatePath) {
		this.templatePath = templatePath;
	}

	private PageResolve() {
	}

	public synchronized static PageResolve getInstance(String templatePath) {
		if (null == pageResolve) {
			pageResolve = new PageResolve();
			pageResolve.setTemplatePath(templatePath);
		}
		return pageResolve;
	}

	/**
	 * 解析html页面信息
	 * 
	 * @param templateName
	 *            json文件名称
	 * @param html
	 *            解析内容
	 * @return
	 */
	public Object parseHtml(String templateName, String html) {
		return parse(templateName, html, false);
	}

	/**
	 * 使用beanshell脚本，脚本的文件名和json的文件名一样，后缀为.bsh
	 * 
	 * @param templateName
	 * @param html
	 * @return
	 */
	public Object parseHtmlWithBsh(String templateName, String html) {
		return parse(templateName, html, true);
	}

	public Object parse(String templateName, String html, boolean isBeanShell) {
		Object obj = null;
		try {
			InputStream conf = super.getClass().getClassLoader().getResourceAsStream(this.templatePath + "/" + templateName + ".json");
			Queryer queryer = makeQueryer(conf);
			if (isBeanShell) {
				InputStream bsh = super.getClass().getClassLoader().getResourceAsStream(this.templatePath + "/" + templateName + ".bsh");
				obj = queryHtml(queryer, html, bsh);
			} else {
				obj = queryer.query(htmlToJsoup(html));
				obj = new JSONObject((Map) obj);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return obj;
	}

	/**
	 * 解析页面内容
	 * 
	 * @param jsonFileString
	 *            : json文件字符串
	 * @param html
	 * @return
	 */
	public Object parseByFileStr(String jsonFileString, String html) {
		return parseByFileStr(html, jsonFileString, null, false);
	}

	public Object parseByFileStrWithBsh(String html, String jsonFileString, String bshFileString) {
		return parseByFileStr(html, jsonFileString, bshFileString, true);
	}

	public Object parseByFileStr(String html, String jsonFileString, String bshFileString, boolean isBeanShell) {
		Object obj = null;
		try {
			Queryer queryer = makeQueryer(jsonFileString);
			if (isBeanShell) {
				obj = queryHtml(queryer, html, bshFileString);
			} else {
				obj = queryer.query(htmlToJsoup(html));
				obj = new JSONObject((Map) obj);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return obj;
	}

	public Queryer makeQueryer(InputStream json) throws JsonException, PageResolveException {
		return JsonQueryerFactory.makeQueryer(json);
	}

	public Queryer makeQueryer(String json) throws JsonException, PageResolveException {
		return JsonQueryerFactory.makeQueryer(json);
	}

	public Document htmlToJsoup(String html) {
		return Jsoup.parse(html);
	}

	public Document htmlToJsoup(InputStream html, String encoding) throws IOException {
		return Jsoup.parse(html, encoding, "");
	}

	public Object bshFilter(Object object, Reader reader) {
		Interpreter bsh = new Interpreter();
		Object result = null;
		try {
			bsh.set("bshResult", object);
			bsh.eval(reader);
			result = bsh.get("bshResult");
		} catch (EvalError e) {
			e.printStackTrace();
		}
		return new JSONObject((Map) result);
	}

	public Object queryHtml(Queryer queryer, String html, String bsh) {
		return bshFilter(queryer.query(htmlToJsoup(html)), new StringReader(bsh));
	}

	public Object queryHtml(Queryer queryer, String html, InputStream bsh) {
		return bshFilter(queryer.query(htmlToJsoup(html)), new InputStreamReader(bsh));
	}
	
	
	public Object bshFilter(Object object, String templateName) {
		InputStream bshFile = super.getClass().getClassLoader().getResourceAsStream(this.templatePath + "/" + templateName + ".bsh");
		Reader reader=new InputStreamReader(bshFile);
		Interpreter bsh = new Interpreter();
		Object result = null;
		try {
			bsh.set("bshResult", object);
			bsh.eval(reader);
			result = bsh.get("bshResult");
		} catch (EvalError e) {
			e.printStackTrace();
		}
		return result;
	}
}
